/**
 * @file ApplyMsg.h
 * @brief Raft 应用消息类定义
 * 
 * 定义了 Raft 向上层状态机提交的消息类型
 * 支持两种消息类型：应用日志命令和安装快照
 * 确保消息类型的互斥性和数据完整性
 */
#ifndef APPLYMSG_H
#define APPLYMSG_H
#include <string>

/**
 * @class ApplyMsg
 * @brief Raft 向上层状态机提交的消息类型
 * 
 * 语义：要么是"应用日志命令"（CommandValid=true），要么是"安装快照"（SnapshotValid=true），二者互斥。
 * 该类封装了 Raft 层向应用层传递的所有必要信息，包括命令数据、索引、快照数据等。
 */
class ApplyMsg {
 public:
  // ========== 日志命令相关字段 ==========
  // 当 CommandValid 为 true 时，表示携带一条需要应用到状态机的日志命令
  bool CommandValid;       ///< 是否为"应用日志命令"的通知；true 表示下方 Command/CommandIndex 字段有效
  std::string Command;     ///< 业务命令的序列化数据（上层负责反序列化并执行）
  int CommandIndex;        ///< 该命令对应的日志索引（通常从 1 开始），用于去重/幂等校验

  // ========== 快照相关字段 ==========
  // 当 SnapshotValid 为 true 时，表示携带一个需要安装到状态机的快照
  bool SnapshotValid;      ///< 是否为"安装快照"的通知；true 表示下方 Snapshot/SnapshotTerm/SnapshotIndex 字段有效
  std::string Snapshot;    ///< 快照的原始数据（以字符串承载，可能包含二进制）；上层负责解码并替换状态机
  int SnapshotTerm;        ///< 生成该快照时的任期号（lastIncludedTerm）
  int SnapshotIndex;       ///< 快照包含的最后一条日志索引（lastIncludedIndex）

 public:
  /**
   * @brief 默认构造函数
   * 
   * 注意：默认将两个 valid 置为 false，防止未初始化误用；
   * 索引/任期设为 -1 表示无效值。Command/Snapshot 默认空。
   * 
   * 初始化规则：
   * - CommandValid = false, SnapshotValid = false（确保消息类型明确）
   * - CommandIndex = -1, SnapshotTerm = -1, SnapshotIndex = -1（无效值标识）
   * - Command 和 Snapshot 为空字符串
   */
  ApplyMsg()
      : CommandValid(false),
        Command(),
        CommandIndex(-1),
        SnapshotValid(false),
        Snapshot(),
        SnapshotTerm(-1),
        SnapshotIndex(-1){

        };
};

#endif  // APPLYMSG_H